package scatter.wxmp.rest.comm;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import me.chanjar.weixin.mp.api.WxMpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import scatter.common.rest.exception.BusinessException;
import scatter.common.rest.tools.HttpClientTool;
import scatter.common.rest.tools.SpringContextHolder;
import scatter.wxmp.pojo.vo.QrCodeTicketVo;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by yangwei
 * Created at 2018/7/20 13:11
 */
public class PublicUtils {

    private static Logger logger = LoggerFactory.getLogger(PublicUtils.class);


    /**
     * @param expireSeconds 最大不超过2592000（即30天）
     * @param sceneId       最大值为100000
     */
    public static QrCodeTicketVo createQrCode(Long expireSeconds, Integer sceneId, String which) {
        return createQrCode(expireSeconds, "QR_SCENE", sceneId, null, which);

    }

    /**
     * @param expireSeconds
     * @param sceneStr
     */
    public static QrCodeTicketVo createQrCode(Long expireSeconds, String sceneStr, String which) {
        return createQrCode(expireSeconds, "QR_STR_SCENE", null, sceneStr, which);

    }

    /**
     * 永久二维码 最多生成10万
     *
     * @param sceneStr
     */
    public static QrCodeTicketVo createQrCodeLimit(String sceneStr, String which) {

        return createQrCode(null, "QR_LIMIT_STR_SCENE", null, sceneStr, which);

    }

    /**
     * 永久二维码 最多生成10万
     *
     * @param sceneId
     */
    public static QrCodeTicketVo createQrCodeLimit(Integer sceneId, String which) {

        return createQrCode(null, "QR_LIMIT_SCENE", sceneId, null, which);
    }

    public static byte[] getQrCode(QrCodeTicketVo qrCodeTicketDto) {
        String url = PublicConstants.SHOW_QRCODE_PARAM.replace(PublicConstants.PARAM_TICKET, qrCodeTicketDto.getTicket());

        try {
            return HttpClientTool.download(url);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("getQrCode error for url = " + url);
        }
    }

    private static QrCodeTicketVo createQrCode(Long expireSeconds, String actionName, Integer sceneId, String sceneStr, String which) {

        Map<String, Object> postParam = new HashMap<>();
        postParam.put("action_name", actionName);
        Map<String, Object> actionInfo = new HashMap<>();
        Map<String, Object> scene = new HashMap<>();

        if (sceneId != null) {
            scene.put("scene_id", sceneId);
        } else if (!StringUtils.isEmpty(sceneStr)) {
            scene.put("scene_str", sceneStr);
        } else {
            throw new BusinessException("scene_id or scene_str can not both be null");
        }

        actionInfo.put("scene", scene);
        postParam.put("action_info", actionInfo);
        if (expireSeconds != null) {
            postParam.put("expire_seconds", expireSeconds);
        }
        String url = "";
        JSONObject jsonObject = null;
        try {
            WxMpService wxMpService = SpringContextHolder.getBean(WxMpService.class);
            wxMpService.switchover(which);
            url = PublicConstants.CREATE_QRCODE_PARAM.replace(PublicConstants.PARAM_ACCESS_TOKEN, wxMpService.getAccessToken());
            jsonObject = new JSONObject(HttpClientTool.httpPostJson(url, JSONUtil.toJsonStr(postParam), null));
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("request failed for url=" + url, e);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("obj2json error", e);
        }
        if (jsonObject != null && jsonObject.get("errcode") != null) {
            Integer errCode = jsonObject.getInt("errcode");
            logger.error("Error occurs when createQrCode, requestUrl:{},error:{}", url, jsonObject);
            if (errCode != 0) {
                throw new RuntimeException(jsonObject.toString());
            }
        } else {

            QrCodeTicketVo qrCodeTicketVo = new QrCodeTicketVo();
            qrCodeTicketVo.setTicket(jsonObject.get("ticket").toString());
            qrCodeTicketVo.setUrl(jsonObject.get("url").toString());
            if (jsonObject.get("expire_seconds") != null) {
                qrCodeTicketVo.setExpireSeconds(jsonObject.getInt("expire_seconds"));
            }
            return qrCodeTicketVo;
        }
        return null;
    }
}
